package com.vecspace.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;

import com.vecspace.utils.log.HLogger;
/**
 * 汉字字符串转成拼音字符串 功能描述
 * @author: wanghua
 */
public class PinYinUtil {
	static PinYinStruct[][] pinYinArray;
	static String encoding = "gb2312";// 必须使用双字节的编码，不能使用utf-8等可能三字节的编码
	static Charset charset = Charset.forName(encoding);

	/**
	 * 初始化拼音库 功能描述：
	 * 
	 * @throws IOException
	 * @author: wanghua
	 */
	private static synchronized void init() throws IOException {
		if (pinYinArray != null) {
			return;
		}
		PinYinStruct[][] pinYinArray2 = new PinYinStruct[255][255];// 占用大约5M内存 255 * 255 * sizeof(PinYinStruct)
		String filepath = "/pinyin.dat";
		InputStream inputStream = PinYinUtil.class.getResourceAsStream(filepath);
		// System.out.println("");
		HLogger.DEFAULT().info("开始加载拼音库... " + filepath);
		InputStreamReader read = new InputStreamReader(inputStream, "utf-8");// 考虑到编码格式
		BufferedReader bufferedReader = new BufferedReader(read);
		try {
			String strln = bufferedReader.readLine(); // 第一行忽略
			strln = bufferedReader.readLine();
			while (strln != null) {
				try {
					String[] arr = strln.split("\t");
					if (arr.length < 5) {
						continue;
					}
					int ordindex = toInt(arr[0], 0);
					String hanzi = arr[1].trim();
					String pinyin = arr[4];
					PinYinStruct pinyinobj = new PinYinStruct();
					pinyinobj.OrderIndex = ordindex;
					pinyinobj.Hanzi = hanzi.charAt(0);
					pinyinobj.YinPin = pinyin.toCharArray();
					byte[] bytes = hanzi.getBytes(charset);// gb.GetBytes(hanzi);
					if (bytes != null && bytes.length == 2) {
						int b1 = bytes[0] & 0xff; // byte 的值是 -128至127，需要转成 0-255
						int b2 = bytes[1] & 0xff;
						if (pinYinArray2[b1][b2] == null) {
							pinYinArray2[b1][b2] = pinyinobj;
						}
					}
				} finally {
					strln = bufferedReader.readLine();
				}
			}
		} finally {
			bufferedReader.close();
		}
		pinYinArray = pinYinArray2;
		HLogger.DEFAULT().info("完成加载拼音库... " + getPinYin("完成加载拼音库...", " "));
	}

	private static int toInt(Object obj, int defaultValue) {
		if (obj == null) {
			return defaultValue;
		}
		try {
			if (obj instanceof Integer) {
				return (Integer) obj;
			} else if (obj instanceof BigDecimal) {
				BigDecimal d = (BigDecimal) obj;
				return d.intValue();
			} else if (obj instanceof Double) {
				Double d = (Double) obj + 0.5;
				return d.intValue();
			} else {
				int n = Integer.parseInt(obj.toString());
				return n;
			}
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * 返回汉字字符串的拼音，无法转成拼音的，返回原字符。均为小写字母 如 北京--> bei jing 北京2014 --> bei jing 2014
	 * 功能描述：
	 * 
	 * @param hanzi 汉字字符串
	 * @param hanzi  拼音之间的间隔符，一般使用 空格" "
	 * @return
	 * @throws IOException
	 * @author: wanghua
	 */
	public static String getPinYin(String hanzi, String splitChar)
			throws IOException {
		if (pinYinArray == null) {
			init();
		}
		if (hanzi == null || hanzi.length() == 0) {
			return "";
		}
		StringBuilder sb = new StringBuilder(10);
		int len = hanzi.length();
		for (int i = 0; i < len; i++) {
			String s = hanzi.substring(i, i + 1);
			byte[] bytes = s.getBytes(charset);
			boolean converted = false;
			if (bytes != null && bytes.length == 2) {
				int b1 = bytes[0] & 0xff;
				int b2 = bytes[1] & 0xff;
				PinYinStruct pinyinobj = pinYinArray[b1][b2];
				if (pinyinobj != null) {
					String str = new String(pinyinobj.YinPin);
					if (sb.length() > 0
							&& !sb.substring(sb.length() - 1, sb.length())
									.equals(splitChar)) {
						sb.append(splitChar);
					}
					sb.append(str).append(splitChar);
					converted = true;
				}
			}
			if (converted == false) {
				sb.append(s);
			}
		}
		return sb.toString().trim();
	}

	/**
	 * 返回汉字字符串的首字母,均为小写字母,无法转成拼音的，返回原字符,#符号取‘号’的首字母h。 如 北京--> bj 北京2014 --> bj2014 功能描述：
	 * 
	 * @param hanzi
	 * @return
	 * @throws IOException
	 * @author: wanghua
	 */
	public static String getFirstZimu(String hanzi) throws IOException {
		if (pinYinArray == null) {
			init();
		}
		if (hanzi == null || hanzi.length() == 0) {
			return "";
		}
		StringBuilder sb = new StringBuilder(10);
		int len = hanzi.length();
		for (int i = 0; i < len; i++) {
			String s = hanzi.substring(i, i + 1);
			byte[] bytes = s.getBytes(charset);

			if (bytes != null && bytes.length == 2) {
				int b1 = bytes[0] & 0xff;
				int b2 = bytes[1] & 0xff;
				PinYinStruct pinyinobj = pinYinArray[b1][b2];
				if (pinyinobj != null) {
					String str = new String(pinyinobj.YinPin);
					sb.append(str.charAt(0));
				}
			} else {
				sb.append(s);
			}
		}
		
		String zmstr = sb.toString();
		zmstr = zmstr.replace('#', 'h');
		return zmstr;
	}
}

class PinYinStruct {
	public int OrderIndex;
	public char Hanzi; // 汉字
	public char[] YinPin; // 拼音
}
